package level4.display.helpers
{
	import flash.display.Bitmap;
	import flash.display.BitmapData;
	import flash.display.DisplayObject;
	import flash.display.PixelSnapping;
	import flash.geom.Matrix;
	import flash.geom.Point;
	import flash.geom.Rectangle;
	import flash.utils.ByteArray;

	public class BitmapHelper
	{
		public function BitmapHelper()
		{
		}
		/**
		 * 只绘制do2d的有效像素 矩形区域,剔除透明区域
		 * */
		public static function filterAlpha(bmd:BitmapData):Bitmap{
			if(bmd){
				var rect:Rectangle = bmd.getColorBoundsRect(0xff000000,0x0,false);
				var newBmd:BitmapData = new BitmapData(rect.width,rect.height,true,0);
					newBmd.draw(bmd,new Matrix(1,0,0,1,-rect.x,-rect.y));
					bmd.dispose();
				return new Bitmap(newBmd);
			}
			return null;
		}
		/**
		 * 框出bmd中有效的像素区域
		 * 过期,使用filterAlpha
		 * */
		public static function __filterAlpha(bmd:BitmapData):Bitmap{
			bmd.lock();
			var rx1:int = findX1(bmd,bmd.width,bmd.height).x;
			var ry1:int = findY1(bmd,bmd.height,bmd.width).y;
			var rx2:int = findX2(bmd,bmd.width,bmd.height).x;
			var ry2:int = findY2(bmd,bmd.height,bmd.width).y;
			//x
			bmd.unlock();
			
			var newBmd:BitmapData = new BitmapData(rx2-rx1,ry2-ry1,false,0);
			var m:Matrix = new Matrix();
			m.translate(-rx1,-ry1);
			newBmd.draw(bmd,m,null,null,new Rectangle(0,0,newBmd.width,newBmd.height));
			return new Bitmap(newBmd);
			
			function findX1(bmd:BitmapData,w:int,h:int):Point{
				for(var i:int =0;i<w;i++){
					for(var j:int=0;j<h;j++){
						var c:uint = (bmd.getPixel32(i,j) >> 24 & 0xff);
						
						if(c > 128){
							return new Point(i,j);
						}
					}
				}
				throw("x1");
			}
			function findY1(bmd:BitmapData,h:int,w:int):Point{
				for(var i:int =0;i<h;i++){
					for(var j:int=0;j<w;j++){
						var c:uint = (bmd.getPixel32(j,i) >> 24 & 0xff);
						
						if(c > 128){
							return new Point(j,i);
						}
					}
				}
				throw("y1");
			}
			
			function findX2(bmd:BitmapData,w:int,h:int):Point{
				for(var i:int =w;i>=0;i--){
					for(var j:int=h;j>=0;j--){
						var c:uint = (bmd.getPixel32(i,j) >> 24 & 0xff);
						if(c > 128){
							return new Point(i,j);
						}
					}
				}
				throw("x2");
			}
			function findY2(bmd:BitmapData,h:int,w:int):Point{
				for(var i:int =h;i>=0;i--){
					for(var j:int=w;j>=0;j--){
						var c:uint = (bmd.getPixel32(j,i) >> 24 & 0xff);
						if(c > 128){
							return new Point(j,i);
						}
					}
				}
				throw("y2");
			}
		}
		/**
		 * 对形变,或注册点不在左上角的do2d进行绘制
		 * */
		public static function drawAfterTransform(do2d:DisplayObject,isApplyRevertMatrix:Boolean=false):Bitmap{
			if(do2d){
				var tf:Object = getAfterTransformBmdAndMatrix(do2d);
				var bmd:BitmapData = tf.bmd;
				var m:Matrix = tf.matrix;
				var bmp:Bitmap = new Bitmap(bmd,PixelSnapping.AUTO,true);
					if(isApplyRevertMatrix){
						m.invert();
						bmp.transform.matrix = m;
					}
				return bmp;
			}
			return null;
		}
		/**
		 * 返回 绘制的bmd及bmd使用的矩阵
		 * {bmd:*,matrix:*}
		 * */
		public static function getAfterTransformBmdAndMatrix(do2d:DisplayObject):Object{
			if(do2d){
				//内部原始矩形,没有形变时,目标在于平移绘制区域
				var innerRect:Rectangle = do2d.getBounds(do2d);
				var sx:Number = Math.abs(do2d.scaleX);
				var sy:Number = Math.abs(do2d.scaleY);
				var tx:int = -innerRect.x * sx;
				var ty:int = -innerRect.y * sy;
				var m:Matrix = new Matrix(sx,0,0,sy,tx,ty);
				var bmd:BitmapData = new BitmapData(innerRect.width * sx,innerRect.height * sy,true,0);
				bmd.draw(do2d,m);
				return {bmd:bmd,matrix:m};
			}
			return null;
		}
		/**
		 * 直接绘制 do2d
		 * */
		public static function drawNormal(do2d:DisplayObject):Bitmap{
			if(do2d){
				var bmd:BitmapData = new BitmapData(do2d.width,do2d.height,true,0);
					bmd.draw(do2d);
				return new Bitmap(bmd,PixelSnapping.AUTO,true);
			}
			return null;
		}
		
		public static function drawScale(bmd:BitmapData,value:Number):Bitmap{
			if(value != 0){
				var newBmd:BitmapData = new BitmapData(bmd.width * value,bmd.height * value,true,0);
					newBmd.draw(bmd,new Matrix(value,0,0,value,0,0));
					bmd.dispose();
				return new Bitmap(newBmd,PixelSnapping.AUTO,true);
			}
			return null;
		}
		
		public static function dispose(bmp:Bitmap):void{
			if(bmp){
				bmp.bitmapData.dispose();
			}
		}
		
		/**
		 * 将BitmapData序列化为ByteArray
		 * 4 : width
		 * 4 : height
		 * 之后为 位图像素字节
		 * */
		public static function Serialized(bmd:BitmapData):ByteArray{
			var bytes:ByteArray = new ByteArray();
				bytes.writeUnsignedInt(bmd.width);
				bytes.writeUnsignedInt(bmd.height);
				bytes.writeBytes(bmd.getPixels(bmd.rect));
				bytes.compress();
			return bytes;
		}
		/**
		 * 将 已序列化的位图数据,还原为 BitmapData
		 * */
		public static function Deserialize(bytes:ByteArray):BitmapData{
			bytes.uncompress();
			var w:int = bytes.readUnsignedInt();
			var h:int = bytes.readUnsignedInt();
			
			var bmd:BitmapData = new BitmapData(w,h);
				bmd.setPixels(bmd.rect,bytes);
			return bmd;
		}
	}
}